<!--
 * 用户管理
 * @author: zhaoyahui
 * @since: 2023-09-09
 * index.vue
-->
<template>
  <div class="main-content">
    <div class="tree margin-r-2">
      <a-input style="margin-bottom: 8px" v-model="searchKey" allow-clear>
        <template #prefix><icon-search /></template>
      </a-input>
      <!-- :default-expand-all默认true，mock空数据时不生效，v-if有数据再加载组件 -->
      <a-scrollbar class="scroll-container">
        <a-tree
          ref="tree"
          :data="treeData"
          v-model:expanded-keys="expandedKeys"
          :field-names="{ key: 'deptId', title: 'deptName' }"
          @select="clickNode"
        >
          <template #switcher-icon="node, { expanded }">
            <span v-if="Boolean(node.children && node.children.length) && expanded" class="iconfont icon-shouqi"></span>
            <span v-else class="iconfont icon-zhankai"></span>
          </template>
          <template #title="nodeData">
            <template v-if="((index = getMatchIndex(nodeData?.deptName)), index < 0)">{{
              nodeData?.deptName
            }}</template>
            <span v-else>
              {{ nodeData?.deptName?.substr(0, index) }}
              <span style="color: var(--color-primary-light-4)">
                {{ nodeData?.deptName?.substr(index, searchKey.length) }} </span
              >{{ nodeData?.deptName?.substr(index + searchKey.length) }}
            </span>
          </template>
        </a-tree>
      </a-scrollbar>
    </div>
    <!-- 搜索 -->
    <TableForm
      ref="formAndTableRef"
      :formItems="formItems"
      :formData="formData"
      :girdOption="girdOption"
      class="tableForm"
      @getTableList="getTableList"
      @selectionChange="selectionChange"
      @handleBtnClick="handleBtnClick"
    >
      <template #btnSlot>
        <div class="line-height-32 fl">
          <a-tag v-for="(item, index) in tagList" :key="index" closable @close="handleClose">{{ item }}</a-tag>
        </div>
      </template>
      <!-- 自定义操作按钮 -->
      <template #tableOptate="{ record }">
        <a-button
          v-for="clickItem in tableOperateList"
          :key="clickItem.text"
          type="text"
          class="operate-item"
          :status="clickItem.eventName == 'tableDel' ? 'danger' : ''"
          @click="handleBtnClick(clickItem.eventName, record)"
        >
          {{ clickItem.text }}
        </a-button>
      </template>
      <!-- 列插槽 -->
      <template #createTime="{ record }">
        {{ record.createTime.slice(0, 10) }}
      </template>
      <template #status="{ record }">
        <a-switch
          v-model="record.status"
          checked-value="0"
          unchecked-value="1"
          :beforeChange="
            (val) => {
              return changeStatus(val, record.userName, record.userId)
            }
          "
        />
      </template>
    </TableForm>
    <AddEditUser v-if="visible" v-model:visible="visible" :rowData="rowData" @submit="getTableList()"></AddEditUser>
    <Import v-if="importVisible" v-model:visible="importVisible"></Import>
    <ResetPwd
      v-if="resetPwdVisible"
      v-model:visible="resetPwdVisible"
      :rowData="rowData"
      @submit="getTableList()"
    ></ResetPwd>
  </div>
</template>

<script setup>
import { reactive, ref, onMounted, computed } from 'vue'
import TableForm from '@/components/tableForm/index.vue'
import AddEditUser from './components/addEditUser.vue' // 新增编辑用户
import Import from './components/import.vue' // 导入
import ResetPwd from './components/resetPwd.vue' // 重置
import { btnList, columns } from './data/index'
import system from '@/api/modules/system'
import { Modal, Message } from '@arco-design/web-vue'

const formData = reactive({ userName: '', phonenumber: '', status: '', dateRange: ['', ''], nickName: '', deptId: '' })
const formAndTableRef = ref()
// 获取字典数据
const statusOptions = ref([])
// 表单配置
const formItems = reactive([
  { name: 'nickName', label: '用户姓名', type: 'a-input' },
  { name: 'userName', label: '用户账号', type: 'a-input' },
  { name: 'phonenumber', label: '手机号码', type: 'a-input' },
  { name: 'status', label: '状态', type: 'a-select', options: statusOptions },
  { name: 'dateRange', label: '创建时间', type: 'a-range-picker' },
])

const girdOption = reactive({
  btnList,
  columns,
  loading: false,
  tableSlotList: ['createTime', 'status'], //表格插槽
  tableId: 'userId', //表格唯一标识符类似于id
  rowSelection: true,
})

// 表格操作插槽
const tableOperateList = reactive([
  { text: '修改', eventName: 'tableEdit' },
  { text: '重置', eventName: 'tableReset' },
  { text: '删除', eventName: 'tableDel' },
])
let visible = ref(false) // 新增编辑弹窗
let importVisible = ref(false) // 导入弹窗
let resetPwdVisible = ref(false) // 重置弹窗
let rowData = reactive({ type: 'add' }) // 弹窗数据

let selectionList = [] // 多选数据
const handleBtnClick = (type, row) => {
  switch (type) {
    case 'add': {
      // 新增
      rowData = { type: 'add' }
      visible.value = true
      break
    }
    case 'delMultiple': {
      //批量删除
      if (!selectionList.length) {
        return Message.warning('请先选择表格数据！')
      }
      Modal.open({
        title: '警告',
        content: `是否确认批量删除已选用户？`,
        draggable: true,
        onOk: () => {
          delUser(selectionList.join(','))
        },
      })
      break
    }
    case 'tableEdit': {
      //编辑
      visible.value = true
      rowData = { ...row, type: 'edit' }
      break
    }
    case 'import': {
      // 导入
      importVisible.value = true
      break
    }
    case 'export': {
      // 导出
      break
    }
    case 'tableReset': {
      // 重置
      resetPwdVisible.value = true
      rowData = { ...row }
      break
    }
    case 'tableDel': {
      //删除
      Modal.open({
        title: '警告',
        content: `是否确认删除用户账号为"${row.userName}" 的数据项？`,
        draggable: true,
        onOk: () => {
          delUser(row.userId)
        },
      })
      break
    }
  }
}
//删除
const delUser = (id) => {
  system.delUser(id).then((res) => {
    getTableList()
    Message.success(res.msg)
  })
}
// 获取表格数据
let requestParam = {}
const getTableList = (pageConfig) => {
  if (pageConfig) {
    requestParam.size = pageConfig.pageSize
    requestParam.current = pageConfig.current
  }
  let param = {
    ...formData,
  }
  param.createTimeStart = param.dateRange[0].length ? param.dateRange[0] + ' 00:00:00' : ''
  param.createTimeStartEnd = param.dateRange[1].length ? param.dateRange[1] + ' 23:59:59' : ''
  delete param.dateRange
  girdOption.loading = true
  system
    .getUserList(param, requestParam)
    .then((res) => {
      formAndTableRef.value.setTableData(res.data.records, Number(res.data.total))
      girdOption.loading = false
    })
    .catch(() => {
      girdOption.loading = false
    })
}
// 多选
const selectionChange = (list) => {
  selectionList = list
}
// 数据字典
const getOption = () => {
  const param = { dictTypes: 'sys_normal_disable' }
  system.getDicts(param).then((res) => {
    statusOptions.value = res.data.sys_normal_disable.map((it) => ({
      label: it.dictLabel,
      value: it.dictValue,
    }))
  })
}
// 部门树
const searchKey = ref('')
const expandedKeys = ref([])
const originTreeData = ref([])
const getTree = () => {
  system.getDeptList().then((res) => {
    originTreeData.value = res.data
    if (res.data.length) {
      formData.deptId = res.data[0].deptId
      expandedKeys.value = [res.data[0].deptId]
      getTableList({ pageSize: 10, current: 1 })
    }
  })
}
const treeData = computed(() => {
  if (!searchKey.value) return originTreeData.value
  return searchData(searchKey.value)
})
// 过滤树
const searchData = (keyword) => {
  const loop = (data) => {
    const result = []
    data.forEach((item) => {
      if (item.deptName.toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
        result.push({ ...item })
      } else if (item.children) {
        const filterData = loop(item.children)
        if (filterData.length) {
          result.push({
            ...item,
            children: filterData,
          })
        }
      }
    })
    return result
  }
  return loop(originTreeData.value)
}
// 搜索词匹配
const getMatchIndex = (title) => {
  if (!searchKey.value) return -1
  return title.toLowerCase().indexOf(searchKey.value.toLowerCase())
}
const tagList = ref([]) // 标签列表
const tree = ref() // 部门树
// 点击树
const clickNode = (selectKeys, it) => {
  if (selectKeys.length) {
    tagList.value = [it.node.deptName]
    formData.deptId = selectKeys[0]
    formAndTableRef.value.setPageCurrent(1) // 设置表格分页器分页为1
    getTableList({ pageSize: 10, current: 1 })
  }
}
// 关闭标签
const handleClose = () => {
  tagList.value = []
  formData.deptId = ''
  getTableList()
  tree.value.selectAll(false)
}
// 切换状态
const changeStatus = async (status, userName, userId) => {
  try {
    await new Promise((resolve, reject) => {
      Modal.open({
        title: '警告',
        content: `确认要${status === '0' ? '启用' : '停用'} "${userName}" 用户吗？`,
        draggable: true,
        onOk: async () => {
          let p = {
            status,
            userId,
          }
          try {
            const res = await system.changeStatusUser(p)
            Message.success(res.msg)
            getTableList()
            resolve()
          } catch (err) {
            reject()
          }
        },
        onCancel: () => {
          reject()
        },
      })
    })
  } catch (err) {
    return false
  }
  return true
}

onMounted(() => {
  getOption()
  // 获取树
  getTree()
})
</script>

<style scoped lang="less">
.main-content {
  display: flex;
}
.tree {
  width: @tree-width;
  background-color: var(--color-bg-2);
  padding: @size-3;
  margin-right: @size-5;
}
:deep(.tree .arco-scrollbar) {
  height: calc(100% - @size-10) !important;
  .scroll-container {
    height: 100%;
    overflow: auto;
  }
}

.tableForm {
  width: calc(100% - @tree-width) !important;
}
</style>
